<template>
  <view class="container">
    <view class="header">
      <view class="title">商品评价</view>
      <view class="subtitle" v-if="productName">{{ productName }}</view>
    </view>
    
    <view class="rating-stats" v-if="stats">
      <view class="overall-rating">
        <text class="rating-number">{{ stats.averageRating || 0 }}</text>
        <view class="star-rating">
          <text 
            v-for="i in 5" 
            :key="i" 
            class="star" 
            :class="{ 'active': i <= Math.round(stats.averageRating || 0) }">★</text>
        </view>
        <text class="rating-count">{{ stats.totalReviews || 0 }}条评价</text>
      </view>
      
      <view class="rating-filters">
        <text 
          class="filter-item" 
          :class="{ 'active': activeFilter === 'all' }" 
          @click="setFilter('all')">全部 ({{ stats.totalReviews || 0 }})</text>
        <text 
          class="filter-item" 
          :class="{ 'active': activeFilter === 'good' }" 
          @click="setFilter('good')">好评 ({{ stats.goodReviews || 0 }})</text>
        <text 
          class="filter-item" 
          :class="{ 'active': activeFilter === 'medium' }" 
          @click="setFilter('medium')">中评 ({{ stats.mediumReviews || 0 }})</text>
        <text 
          class="filter-item" 
          :class="{ 'active': activeFilter === 'bad' }" 
          @click="setFilter('bad')">差评 ({{ stats.badReviews || 0 }})</text>
        <text 
          class="filter-item" 
          :class="{ 'active': activeFilter === 'hasImages' }" 
          @click="setFilter('hasImages')">有图 ({{ stats.hasImageReviews || 0 }})</text>
      </view>
    </view>
    
    <view v-if="loading && page === 1" class="loading">
      <view class="loading-spinner"></view>
      <text>加载中...</text>
    </view>
    
    <view v-else-if="reviews.length === 0" class="empty-state">
      <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image>
      <text class="empty-text">暂无评价内容</text>
    </view>
    
    <scroll-view 
      v-else 
      scroll-y 
      class="reviews-list"
      @scrolltolower="loadMore"
    >
      <view v-for="review in reviews" :key="review.id" class="review-item">
        <view class="review-header">
          <image :src="review.userAvatar || '/static/images/default-avatar.png'" class="user-avatar" />
          <view class="review-info">
            <text class="username">{{ review.isAnonymous ? '匿名用户' : (review.username || '用户') }}</text>
            <view class="rating">
              <text v-for="i in 5" :key="i" class="star" :class="{ active: i <= review.rating }">★</text>
            </view>
          </view>
          <text class="review-time">{{ formatDate(review.createdAt) }}</text>
        </view>
        
        <text class="review-content">{{ review.comment }}</text>
        
        <view class="review-images" v-if="review.images && formatImages(review.images).length > 0">
          <image 
            v-for="(image, index) in formatImages(review.images)" 
            :key="index" 
            :src="image" 
            class="review-image" 
            mode="aspectFill"
            @click="previewImage(formatImages(review.images), index)"
          ></image>
        </view>
        
        <view class="review-spec" v-if="review.specifications">
          <text>{{ review.specifications }}</text>
        </view>
      </view>
      
      <view v-if="loading && page > 1" class="loading-more">
        <view class="loading-spinner small"></view>
        <text>加载更多中...</text>
      </view>
      
      <view v-if="!loading && !hasMore" class="no-more">
        <text>没有更多评价了</text>
      </view>
    </scroll-view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
import { reviewApi } from '../../api/review.js';

// 响应式数据
const productId = ref(null);
const productName = ref('');
const reviews = ref([]);
const page = ref(1);
const pageSize = ref(10);
const loading = ref(false);
const hasMore = ref(true);
const stats = ref(null);
const activeFilter = ref('all');

// 接收页面参数
onLoad((options) => {
  if (options.productId) {
    productId.value = options.productId;
    if (options.productName) {
      productName.value = decodeURIComponent(options.productName);
    }
    loadReviewStats();
    loadReviews();
  } else {
    uni.showToast({
      title: '商品ID不存在',
      icon: 'none'
    });
  }
});

// 加载评价统计数据
const loadReviewStats = async () => {
  try {
    const res = await reviewApi.getReviewStats(productId.value);
    if (res.code === 200 && res.data) {
      stats.value = res.data;
    } else {
      // 如果API不可用，使用默认统计数据
      console.error('评价统计API未正确返回数据:', res);
      setDefaultStats();
    }
  } catch (error) {
    console.error('加载评价统计数据失败:', error);
    // 如果发生错误，使用默认统计数据
    setDefaultStats();
  }
};

// 设置默认统计数据
const setDefaultStats = () => {
  // 创建默认统计数据，稍后从实际评价中计算
  stats.value = {
    averageRating: 0,
    totalReviews: 0,
    goodReviews: 0,
    mediumReviews: 0,
    badReviews: 0,
    hasImageReviews: 0
  };
  
  // 第一次加载完评价后更新统计数据
  refreshStatsFromReviews();
};

// 从已加载的评价中计算统计数据
const refreshStatsFromReviews = () => {
  if (!stats.value || reviews.value.length === 0) return;
  
  let totalRating = 0;
  let goodCount = 0;
  let mediumCount = 0;
  let badCount = 0;
  let hasImageCount = 0;
  
  reviews.value.forEach(review => {
    totalRating += review.rating || 0;
    
    if (review.rating >= 4) {
      goodCount++;
    } else if (review.rating >= 2) {
      mediumCount++;
    } else {
      badCount++;
    }
    
    if (review.images && formatImages(review.images).length > 0) {
      hasImageCount++;
    }
  });
  
  stats.value.totalReviews = reviews.value.length;
  stats.value.averageRating = reviews.value.length > 0 ? (totalRating / reviews.value.length).toFixed(1) : 0;
  stats.value.goodReviews = goodCount;
  stats.value.mediumReviews = mediumCount;
  stats.value.badReviews = badCount;
  stats.value.hasImageReviews = hasImageCount;
};

// 获取筛选条件
const getFilterParams = () => {
  const params = {
    page: page.value,
    pageSize: pageSize.value
  };
  
  // 根据筛选条件添加参数
  switch (activeFilter.value) {
    case 'good':
      params.minRating = 4;
      break;
    case 'medium':
      params.minRating = 2;
      params.maxRating = 3;
      break;
    case 'bad':
      params.maxRating = 1;
      break;
    case 'hasImages':
      params.hasImages = true;
      break;
  }
  
  return params;
};

// 加载评价
const loadReviews = async () => {
  if (loading.value) return;
  loading.value = true;
  
  try {
    const params = getFilterParams();
    const res = await reviewApi.getProductReviewPage(productId.value, params);
    
    if (res.code === 200) {
      const data = res.data;
      
      if (page.value === 1) {
        reviews.value = data.records || [];
        
        // 第一页加载完成后，如果需要，更新统计数据
        if (!stats.value || !stats.value.totalReviews) {
          refreshStatsFromReviews();
        }
      } else {
        reviews.value = [...reviews.value, ...(data.records || [])];
      }
      
      // 判断是否有更多数据
      hasMore.value = data.current < data.pages;
      
    } else {
      uni.showToast({
        title: '获取评价失败',
        icon: 'none'
      });
    }
  } catch (error) {
    console.error('加载评价失败:', error);
    uni.showToast({
      title: '加载失败，请重试',
      icon: 'none'
    });
  } finally {
    loading.value = false;
  }
};

// 加载更多
const loadMore = () => {
  if (!loading.value && hasMore.value) {
    page.value++;
    loadReviews();
  }
};

// 设置筛选条件
const setFilter = (filter) => {
  if (activeFilter.value === filter) return;
  
  activeFilter.value = filter;
  page.value = 1;
  loadReviews();
};

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return '';
  
  try {
    const date = new Date(dateString.replace(/-/g, '/').replace('T', ' ').split('.')[0]);
    return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
  } catch (e) {
    console.error('日期格式化错误:', e);
    return dateString;
  }
};

// 格式化图片数组，处理JSON字符串格式
const formatImages = (images) => {
  if (!images) return [];
  
  try {
    if (typeof images === 'string') {
      return JSON.parse(images);
    }
    return images;
  } catch (e) {
    console.error('解析图片数据失败:', e);
    return [];
  }
};

// 预览图片
const previewImage = (images, index) => {
  uni.previewImage({
    urls: images,
    current: index
  });
};
</script>

<style>
.container {
  padding: 30rpx;
  background-color: #f8f8f8;
  min-height: 100vh;
}

.header {
  margin-bottom: 30rpx;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 10rpx;
}

.subtitle {
  font-size: 28rpx;
  color: #666;
}

.loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 100rpx 0;
}

.loading-spinner {
  width: 60rpx;
  height: 60rpx;
  border: 4rpx solid #f3f3f3;
  border-top: 4rpx solid #ff6700;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 20rpx;
}

.loading-spinner.small {
  width: 40rpx;
  height: 40rpx;
  border-width: 3rpx;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 100rpx 0;
}

.empty-image {
  width: 200rpx;
  height: 200rpx;
  margin-bottom: 30rpx;
}

.empty-text {
  font-size: 32rpx;
  color: #999;
}

.reviews-list {
  height: calc(100vh - 300rpx);
}

.review-item {
  background-color: #fff;
  border-radius: 16rpx;
  padding: 30rpx;
  margin-bottom: 20rpx;
}

.review-header {
  display: flex;
  align-items: center;
  margin-bottom: 20rpx;
}

.user-avatar {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  background-color: #f5f5f5;
}

.review-info {
  flex: 1;
  margin-left: 20rpx;
}

.username {
  font-size: 28rpx;
  color: #333;
  font-weight: bold;
  margin-bottom: 6rpx;
}

.rating {
  display: flex;
}

.star {
  font-size: 28rpx;
  color: #ddd;
  margin-right: 4rpx;
}

.star.active {
  color: #ff6700;
}

.review-time {
  font-size: 24rpx;
  color: #999;
}

.review-content {
  font-size: 28rpx;
  color: #333;
  line-height: 1.5;
  margin-bottom: 20rpx;
}

.review-images {
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 20rpx;
}

.review-image {
  width: 160rpx;
  height: 160rpx;
  margin-right: 20rpx;
  margin-bottom: 20rpx;
  border-radius: 8rpx;
  background-color: #f5f5f5;
}

.review-spec {
  display: inline-block;
  font-size: 24rpx;
  color: #999;
  background-color: #f8f8f8;
  padding: 6rpx 16rpx;
  border-radius: 20rpx;
}

.loading-more, .no-more {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30rpx 0;
}

.loading-more {
  display: flex;
  align-items: center;
}

.loading-more text {
  font-size: 26rpx;
  color: #999;
  margin-left: 10rpx;
}

.no-more text {
  font-size: 26rpx;
  color: #999;
}

.rating-stats {
  background-color: #fff;
  border-radius: 16rpx;
  padding: 30rpx;
  margin-bottom: 20rpx;
}

.overall-rating {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 30rpx;
}

.rating-number {
  font-size: 64rpx;
  font-weight: bold;
  color: #ff6700;
  margin-right: 30rpx;
}

.overall-rating .star-rating {
  display: flex;
  margin-right: 20rpx;
}

.overall-rating .star {
  font-size: 32rpx;
  margin-right: 8rpx;
}

.rating-count {
  font-size: 26rpx;
  color: #999;
}

.rating-filters {
  display: flex;
  flex-wrap: wrap;
}

.filter-item {
  background-color: #f5f5f5;
  color: #666;
  font-size: 26rpx;
  padding: 12rpx 24rpx;
  border-radius: 30rpx;
  margin-right: 20rpx;
  margin-bottom: 16rpx;
}

.filter-item.active {
  background-color: #fff0e6;
  color: #ff6700;
  border: 1rpx solid #ff6700;
}
</style> 